package com.robam.cloud.common.util;

import com.alipay.api.internal.util.file.IOUtils;
import com.robam.cloud.common.bean.restful.entity.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
public class FileUtil {

    /**
     * 获得文件名
     * 4位随机数加上当前时间
     *
     * @return
     */
    //定义上传的文件夹
    //private static final String UPLOAD_PATH = "E:/save";
    //定义水印文字样式
    private static final String FONT_NAME = "微软雅黑";
    private static final int FONT_STYLE = Font.BOLD;
    private static final int FONT_SIZE = 360;
    private static final Color FONT_COLOR = Color.black;


    public static String genFileName() {
        String name = longToNBuf(System.currentTimeMillis(), N36_CHARS).reverse().toString();
        return RandomStringUtils.random(4, N36_CHARS) + name;
    }

    private static final char[] N36_CHARS = {'0', '1', '2', '3', '4', '5', '6',
            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
            'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
            'x', 'y', 'z'};

    private static StringBuilder longToNBuf(long l, char[] chars) {
        int upgrade = chars.length;
        StringBuilder result = new StringBuilder();
        int last;
        while (l > 0) {
            last = (int) (l % upgrade);
            result.append(chars[last]);
            l /= upgrade;
        }
        return result;
    }

    //计算水印文本长度
    //1、中文长度即文本长度 2、英文长度为文本长度二分之一
    public static int getTextLength(String text) {
        //水印文字长度
        int length = text.length();

        for (int i = 0; i < text.length(); i++) {
            String s = String.valueOf(text.charAt(i));
            if (s.getBytes().length > 1) {
                length++;
            }
        }
        length = length % 2 == 0 ? length / 2 : length / 2 + 1;
        return length;
    }

    //添加单条文字水印方法
    public static MultipartFile textWaterMark(MultipartFile myFile, String MARK_TEXT) {
        String fileName = myFile.getOriginalFilename();// 原文件名
        String suffix = getSuffixByFileName(fileName);// 原文件后缀
        InputStream is = null;
        try {
            //使用ImageIO解码图片
            Image image = ImageIO.read(myFile.getInputStream());
            //计算原始图片宽度长度
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            //创建图片缓存对象
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //创建java绘图工具对象
            Graphics2D graphics2d = bufferedImage.createGraphics();
            //参数主要是，原图，坐标，宽高
            graphics2d.drawImage(image, 0, 0, width, height, null);
            graphics2d.setFont(new Font(FONT_NAME, FONT_STYLE, FONT_SIZE));
            graphics2d.setColor(FONT_COLOR);

            //使用绘图工具将水印绘制到图片上
            //计算文字水印宽高值
            int waterWidth = FONT_SIZE * getTextLength(MARK_TEXT);
            int waterHeight = FONT_SIZE;
            //计算水印与原图高宽差
            int widthDiff = (width - waterWidth) / 2;
            int heightDiff = (height + waterHeight) / 2;
            //水印透明设置
            graphics2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.2f));
            //纵坐标在下方，不增加字体高度会靠上
            graphics2d.drawString(MARK_TEXT, widthDiff, heightDiff);

            graphics2d.dispose();
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, suffix, os);
            InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
            MultipartFile multipartFile = new MockMultipartFile(fileName, fileName, "image/jpeg", inputStream);
            if (is != null) {
                is.close();
            }
            if (os != null) {
                os.close();
            }
            return multipartFile;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据文件全名获得后缀（小写）
     *
     * @param fileName
     * @return
     */
    public static String getSuffixByFileName(String fileName) {
        int start = fileName.lastIndexOf(".");
        if (start == -1) {
            return null;
        } else {
            return fileName.substring(start + 1).toLowerCase();
        }
    }

    public static Date strToDateLong(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }

    public static String dateToStrLong(Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * @return void
     * @throws
     * @Description 下载base64的文件存到targePath地址（非线提供的下载pdf方法）
     * @Date 9:21 2019/7/25
     * @Param [base64Code, targetPath]
     */
    public static void decoderBase64File(String base64Code, String targetPath)
            throws Exception {
        byte[] buffer = new BASE64Decoder().decodeBuffer(base64Code);
        FileOutputStream out = new FileOutputStream(targetPath);
        out.write(buffer);
        out.close();
    }

    public static MultipartFile urlToMultipartFile(String url) {
        URL ur = null;
        InputStream is = null;
        try {
            ur = new URL(url);
            is = ur.openStream();
            URLConnection conn = ur.openConnection();
            String contentType = conn.getHeaderField("Content-Type");
            String disposition = conn.getHeaderField("Content-Disposition");
            String fullFileName = "";
            if (StringUtil.isNotEmpty(disposition)) {
                int index = disposition.indexOf("filename");
                if (index > 0) {
                    fullFileName = disposition.substring(disposition.lastIndexOf("=") + 2, disposition.length() - 1);
                }
            } else {
                fullFileName = url.substring(url.lastIndexOf("/") + 1, url.length());
            }

            MultipartFile toMultipartFile = new MockMultipartFile("file", fullFileName, contentType, IOUtils.toByteArray(is));
            return toMultipartFile;
        } catch (Exception e) {
            log.error("文件读取异常{}", e);
            throw new ServiceException("文件读取异常");
        }
    }
}
